﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Reflection;
using SenerPro;

namespace MensUnoShop.Models
{
    [Serializable]
    public class ShoppingCart
    {
        private Guid _scguid;
        private List<OrderMarket> _mlist;
        private List<ITradeInDiscount> _dsklist;
        private List<SalesKit> _skgiftlist;
        private int _deliverycost;
        //購物賣場總金額
        private int _total;
        //須付費金額
        private int _payprice;
        private Guid _pdguid;
        private string _specid;
        private int _amount;
        private DateTime _lastaccess;
        [NonSerialized]
        private SenerPro.Logger _log;
        [NonSerialized]
        private DBOrder _repository;

        public Guid SCGUID { set { _scguid = value; } get { return _scguid; } }
        public List<OrderMarket> MLIST { set { _mlist = value; } get { return _mlist; } }
        public List<ITradeInDiscount> DSKLIST { set { _dsklist = value; } get { return _dsklist; } }
        public List<SalesKit> SKGIFTLIST { set { _skgiftlist = value; } get { return _skgiftlist; } }
        public int DELIVERYCOST { set { _deliverycost = value; } get { return _deliverycost; } }
        public int TOTAL { set { _total = value; } get { return _total; } }
        public int PAYPRICE { set { _payprice = value; } get { return _payprice; } }

        public ShoppingCart()
        {
            _mlist = new List<OrderMarket>();
            _dsklist = new List<ITradeInDiscount>();
            _skgiftlist = new List<SalesKit>();
            _scguid = Guid.NewGuid();
            _log = new Logger(Config.logpath);
        }

        public void CalShoppingCart()
        {
            //設定運費
            setDeliveryCost();
            //賣場總金額小計
            _total = _mlist.Sum(m => m.PRICE)+_deliverycost;
            int tempdiscount = _dsklist.Sum(dsk => dsk.DEPRICE);
            _payprice = _total - tempdiscount;
            //設定行銷活動(贈品類)
            setGiftSalesKit();
        }

        private void setGiftSalesKit()
        {
            Logger _log = new Logger(Config.logpath);
            try
            {
                List<long> clist = new List<long>();
                _skgiftlist = SalesKitFactory.GetByOrderGiftSalesKitList();
                Order tempo = new Order();
                tempo.MLIST = _mlist;
                tempo.PAYPRICE = _payprice;
                foreach (IOrderSalesKit sk in _skgiftlist)
                {
                    sk.Judge(tempo);
                }
            }
            catch (Exception ex)
            {
                _log.RecordException(_log.FlowLogPath, "[SetGiftSalesKit]" + ex.ToString());
            }
        }

        /// <summary>
        /// 設定購物賣場訂購數量
        /// </summary>
        /// <param name="mokguid">該購物賣場guid</param>
        /// <param name="num">變更數量</param>
        public bool SetMarketAmount(Guid mokguid, int num)
        {
            bool isset = false;
            var m = _mlist.SingleOrDefault(om => om.MOKGUID == mokguid);
            if (m != null)
            {
                IMarket im = MarketFactory.GetMarket(m.MKGUID,m.TYPE);
                //設定賣場實體
                if (im != null)
                    isset = im.SetMarketAmount(ref m, _scguid, num);

                if (isset)
                {
                    CalShoppingCart();
                    SaveToCookie();
                }
            }
            return isset;
        }

        /// <summary>
        /// 移除購物車賣場
        /// </summary>
        public void Remove(Guid mokguid)
        {
            var m = _mlist.SingleOrDefault(om => om.MOKGUID == mokguid);
            if (m != null)
            {
                if (m.TYPE == Config.MarketType.Combo)
                {
                    var combolist = _mlist.Where(om => om.COMBOID == m.COMBOID);
                    foreach (var co in combolist)
                    {
                        removeShoppingCart(co.MOKGUID, false);
                    }
                    _mlist.RemoveAll(om => om.COMBOID == m.COMBOID);
                }
                else
                {
                    if (removeShoppingCart(mokguid, false))
                    {
                        _mlist.Remove(m);
                    }
                }
            }
            CalShoppingCart();
            SaveToCookie();
        }
        public void RemoveAll()
        {
            if (removeShoppingCart(null, true))
                _mlist.Clear();
            CalShoppingCart();
            SaveToCookie();
        }

        /// <summary>
        /// 保存購物車
        /// </summary>
        public void SaveToCookie()
        {
            _lastaccess = DateTime.Now;
            HttpContext.Current.Session["sk"] = this;
            HttpCookie hc = new HttpCookie("scguid", _scguid.ToString("N"));
            hc.Domain = HttpContext.Current.Request.Url.Host.ToString();
            hc.Value = _scguid.ToString("N");
            HttpContext.Current.Response.Cookies.Add(hc);
        }

        public void FreeCookie()
        {
            try
            {
                HttpCookie hc = new HttpCookie("scguid");
                hc.Value = string.Empty;
                hc.Expires = DateTime.Now.AddDays(-1);
                HttpContext.Current.Response.Cookies.Add(hc);
                HttpContext.Current.Session["sk"] = null;
            }
            catch
            {
                HttpContext.Current.Session["sk"] = null;
            }

        }

        /// <summary>
        /// 轉導頁面，將購物車轉成binary
        /// </summary>
        /// <param name="mguid">會員GUID</param>
        public void SaveToDatabase(Guid mguid)
        {
            SetRepository();
            _repository.SaveShoppingCart(this.SCGUID, mguid, _lastaccess);
        }

        /// <summary>
        ///   1. 判斷購物車存不存在
        ///   2. 判斷賣場存不存在購物車
        ///   3. 判斷商品存不存在購物車
        ///   4. 判斷商品合不合法
        ///   5. 加入購物車
        /// </summary>
        /// <param name="ac"></param>
        /// <param name="scguid"></param>
        /// <returns></returns>
        public bool ChkMarket(Guid mkguid, Guid productid, string specid, int amount,Config.MarketType mktype, out string error)
        {
            error = string.Empty;
            bool chk = false;
            if (_mlist.Count == 100)
            {
                error = "購物車已達上限，請先結帳，謝謝。";
                return chk;
            }
            else
            {
                _pdguid = productid;
                _specid = specid;
                _amount = amount;
                IMarket im = MarketFactory.GetMarket(mkguid,mktype);

                //檢查該賣場商品數量是否足夠(若足夠則扣庫存)
                
                if (im != null)
                {
                    chk = im.CheckMarket(_scguid, ref _mlist, new Guid[]{_pdguid}, new string[]{_specid}, new int[]{_amount}, ref error);
                }

                return chk;
            }
        }

        //合購用
        public bool ChkMarket(Guid[] mkguid, Guid[] productid, Guid[] specid, int comboid, out string error)
        {
            error = string.Empty;
            bool chk = false;
            if (_mlist.Count == 100)
            {
                error = "購物車已達上限，請先結帳，謝謝。";
                return chk;
            }
            else
            {
                for(int i=0;i<mkguid.Length;i++)
                {
                    _pdguid = productid[i];
                    _specid = specid[i].ToString();
                    _amount = 1;
                    IMarket im = MarketFactory.GetMarket(mkguid[i], Config.MarketType.Combo);
                    
                    //檢查該賣場商品數量是否足夠(若足夠則扣庫存)
                    if (im != null)
                    {
                        im.TAGID = comboid;
                        chk = im.CheckMarket(_scguid, ref _mlist, new Guid[] { _pdguid }, new string[] { _specid }, new int[] { _amount }, ref error);
                    }
                    if (!chk)
                    {
                        MLIST.RemoveAll(m => m.COMBOID == comboid);
                        break;
                    }
                }

                if (chk)
                {
                    //計算合購
                    USalesKit sk = SalesKitFactory.GetCombo(comboid);
                    var combolist = _mlist.Where(m => m.TYPE == Config.MarketType.Combo && m.COMBOID == comboid);
                    var fcombo = combolist.FirstOrDefault();
                    int pices = int.Parse(sk.SSnote.Split('|')[0]);
                    int comboprice = int.Parse(sk.SSnote.Split('|')[1]);
                    fcombo.AMOUNT = combolist.Count() / pices;
                    fcombo.SINGLEPRICE = comboprice;
                    fcombo.PRICE = fcombo.AMOUNT * fcombo.SINGLEPRICE;

                    foreach (var c in combolist.Where(cm => cm.MOKGUID != fcombo.MOKGUID))
                    {
                        c.SINGLEPRICE = c.PRICE = c.AMOUNT = 0;
                    }
                }
                return chk;
            }
        }

        public static bool Check(Guid scguid, Guid mguid)
        {
            DBOrder dbo = new DBOrder();
            bool isexist = false;
            try
            {
                isexist = dbo.CheckTemp(scguid, mguid);
            }
            catch (Exception ex)
            {
                Logger log = new Logger(System.Configuration.ConfigurationManager.AppSettings["logpath"].ToString());
                log.RecordException(log.DBExceptionPath, ex.ToString());
            }
            return isexist;
        }

        public static ShoppingCart GetShoppingCart()
        {
            ShoppingCart sc = null;
            if (HttpContext.Current.Session["sk"] != null)
            {
                try
                {
                    sc = (ShoppingCart)HttpContext.Current.Session["sk"];
                }
                catch
                {
                    sc = new ShoppingCart();
                }
            }
            else
                sc = new ShoppingCart();

            return sc;
        }




        /// <summary>
        /// 運費規則寫在這裡
        /// </summary>
        private void setDeliveryCost()
        {
            _deliverycost = 0;
        }

        //移除購物賣場
        private bool removeShoppingCart(object mokguid, bool isall)
        {
            bool freespec = false;
            if (isall)
                freespec = (MarketFactory.FreeSpecStock(_scguid));
            else
                freespec = (MarketFactory.FreeSpecStock(_scguid, (Guid)mokguid));
            return freespec;
        }

        private void SetRepository()
        {
            if (_repository == null)
                _repository = new DBOrder();
        }
    }
}
